package com.us.example.service;

import com.alibaba.fastjson.JSONObject;
import com.us.example.dao.PermissionDao;
import com.us.example.dao.UserDao;
import com.us.example.domain.JwtUser;
import com.us.example.domain.JwtUserDto;
import com.us.example.domain.Permission;
import com.us.example.domain.SysUser;
import com.us.example.security.UrlGrantedAuthority;
import io.jsonwebtoken.impl.JwtMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class CustomUserService implements UserDetailsService { //自定义UserDetailsService 接口

    @Autowired
    UserDao userDao;
    @Autowired
    PermissionDao permissionDao;
    @Autowired
    private RedisService redisService;


    public UserDetails loadUserByUsername(String username) {
        JwtUserDto jwtUserDto;

        //这里先去redis查看有没有key，如果有则去获取用户信息，连续调用两次感觉不太好，这里就不优化了
        if(RedisCheckUser(username) !=null){
            jwtUserDto=RedisCheckUser(username);
            List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
            Map JwtMap = getPermissUrlandMethod(jwtUserDto);
            for(Object key : JwtMap.keySet()){
                Object value = JwtMap.get(key);
                GrantedAuthority grantedAuthority = new UrlGrantedAuthority((String) key,(String)value);
                grantedAuthorities.add(grantedAuthority);
            }

            return new JwtUser(jwtUserDto.getUsername(), jwtUserDto.getPassword(), grantedAuthorities);

        }else{
            //如果redis里边没有缓存用户信息，说明可能是第一次登录，所以要去数据库查信息
            JwtUser user;
            user = userDao.findByUserName(username);
            if(user.getId() != null){
                List<Permission> permissions = permissionDao.findByAdminUserId(user.getId());
                List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
                for (Permission permission : permissions) {
                    if (permission != null && permission.getName() != null) {
                        GrantedAuthority grantedAuthority = new UrlGrantedAuthority(permission.getPermissionUrl(),permission.getMethod());
                        grantedAuthorities.add(grantedAuthority);
                    }
                }
                return new JwtUser(user.getUsername(), user.getPassword(), grantedAuthorities);
            }else{
                throw new UsernameNotFoundException("admin: " + username + " do not exist!");
            }
        }

    }

    public JwtUserDto RedisCheckUser(String username) {

        //从redis里边取出用户信息
        String stringValue = redisService.get("springsecurity3"+":"+username);

        if (stringValue != null) {
            try {
                // 验证当前请求的session是否是已登录的session
                //json转成JwtUser对象
                JwtUserDto jwtUserDto = JSONObject.parseObject(stringValue,JwtUserDto.class);
                return jwtUserDto;
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    }

    //因为jwtUserDto里边存的是一个List集合，然后List集合里边是Map，所以要在这里把数据拆开再组装，只返回一个带有权限的Map
    public Map getPermissUrlandMethod(JwtUserDto jwtUserDto){
        Map jwtMapDto = new HashMap();
        List jwtList = (List) Collections.singletonList(jwtUserDto.getAuthorities()).get(0);
        for(int i =0;i<jwtList.size();i++){
            Map jwtMap = (Map) jwtList.get(i);
            String PermissionUrlS = (String) jwtMap.get("permissionUrl");
            String methodS = (String) jwtMap.get("method");
            jwtMapDto.put(PermissionUrlS,methodS);
        }
        return jwtMapDto;
    }
}
